<template>
  <pro-provider :content-width="contentWidth">
    <a-layout class="ant-pro-leftmenu-layout">
      <sider-menu
        v-model:collapsed="collapsed"
        theme="dark"
        layout="left"
        prefix-cls="ant-pro-leftmenu-sider"
        :fixed="true"
        :menus="mainMenus"
        :sider-width="sideWidth"
        :collapsed-width="collapsedWidth"
        :open-keys="[]"
        :selected-keys="firstSelectedKeys"
        :custom-item="customItem"
        @item-hover="handleItemHover"
        @mouseleave="handleMouseLeave"
        @update:selected-keys="handleSelectedKeysChange"
      ></sider-menu>
      <a-layout style="position: relative; flex-direction: column">
        <header-view
          :theme="theme"
          :layout="layout"
          :menus="menus"
          :has-sider-menu="true"
          :fixed-header="true"
          :split-menus="splitMenus"
          :collapsed-button="false"
          :collapsed-width="collapsed ? collapsedWidth : sideWidth"
          :selected-keys="[]"
          :open-keys="[]"
        >
          <div style="text-align: right" class="flex items-center">
            <notice-icon />
            <avatar-dropdown :current-user="currentUser" />
            <select-lang />
          </div>
        </header-view>
        <a-layout style="width: auto">
          <sider-menu
            key="menu"
            v-model:open-keys="openKeys"
            v-model:selected-keys="selectedKeys"
            :style="{
              zIndex: 7,
              position: 'fixed',
              left: `${collapsed ? collapsedWidth : sideWidth}px`,
            }"
            class="ant-pro-has-leftmenu"
            theme="light"
            :layout="layout"
            :fixed="true"
            :menus="menus"
            :sider-width="secondSideWidth"
            :split-menus="true"
            :collapsed-button="false"
            :collapsed="false"
          ></sider-menu>
          <section style="flex: auto; overflow-x: hidden" class="ant-pro-leftmenu-layout-content">
            <wrap-content>
              <router-view />
              <slot />
            </wrap-content>
            <global-footer />
          </section>
        </a-layout>
        <div
          v-show="showHoverSiderMenu"
          :style="{
            position: 'fixed',
            left: `${collapsed ? collapsedWidth : sideWidth}px`,
            zIndex: 8,
            height: '100%',
          }"
          @mouseenter="cancelSetMenuHover"
          @mouseleave="handleMouseLeave"
        >
          <sider-menu
            key="hoverMenu"
            v-model:open-keys="openKeys"
            v-model:selected-keys="selectedKeys"
            :style="{ height: '100%' }"
            class="ant-pro-has-leftmenu"
            theme="light"
            :layout="layout"
            :fixed="false"
            :menus="secondMenus"
            :sider-width="secondSideWidth"
            :collapsed-button="false"
            :collapsed="false"
          ></sider-menu>
        </div>
      </a-layout>
    </a-layout>
    <setting-drawer />
  </pro-provider>
</template>

<script lang="ts" setup>
import type { VNode } from 'vue';
import { ref, computed, watch, cloneVNode } from 'vue';
import { genMenuInfo, getMenuFirstChildren } from '@/utils/menu-util';
import useDelayReset from '@/utils/hooks/useDelayReset';
import { default as WrapContent } from '@/components/base-layouts/wrap-content/index.vue';
import { default as GlobalFooter } from '@/components/base-layouts/global-footer/index.vue';
import { default as SiderMenu } from '@/components/base-layouts/sider-menu/index.vue';
import { default as HeaderView } from '@/components/base-layouts/header/index.vue';
import { default as SelectLang } from '@/components/select-lang/index.vue';
import { default as AvatarDropdown } from '@/components/avatar-dropdown.vue';
import { default as SettingDrawer } from '@/components/setting-drawer/index.vue';
import { injectMenuState } from './use-menu-state';
import { default as NoticeIcon } from '@/components/notice-icon/index.vue';
import { useUserStore } from '@/store/user';
import type { RouteRecordRaw } from 'vue-router';
const userStore = useUserStore();
const currentUser = computed(() => userStore.currentUser);

// gen menus
const allowRouters = computed(() => userStore.allowRouters); // genMenuInfo(filterMenu(routes)).menus;
const menus = computed(() => genMenuInfo(allowRouters.value as RouteRecordRaw[]).menus);
const mainMenus = computed(() => getMenuFirstChildren(menus.value));
const {
  collapsed,
  openKeys,
  selectedKeys,
  updateSelectKeys,
  sideWidth,
  collapsedWidth,
  theme,
  layout,
  splitMenus,
  contentWidth,
  secondSideWidth,
} = injectMenuState();
const firstSelectedKeys = computed(() => {
  const key = selectedKeys ? selectedKeys.value[0] : undefined;
  return key ? [`/${key.split('/')[1]}`] : [];
});
const [menuHover, setMenuHover, cancelSetMenuHover] = useDelayReset(100);
const hoverMenuKey = ref('');
const handleItemHover = (item: { key: string }) => {
  cancelSetMenuHover();
  menuHover.value = true;
  hoverMenuKey.value = item.key;
};
const handleSelectedKeysChange = (keys: string[]) => {
  const menu = menus.value.find(m => m.path === keys[0]);
  const toKey = menu && menu.redirect ? [menu.redirect] : keys;
  updateSelectKeys(toKey);
};
const handleMouseLeave = () => {
  setMenuHover(false);
};
watch(menuHover, () => {
  // 重置为空
  if (!menuHover.value) {
    hoverMenuKey.value = '';
  }
});
const secondMenus = computed(() => {
  return menus.value.find(m => m.path === hoverMenuKey.value)?.children || [];
});
// 是否展示hover一级时，展示对应的二级菜单
const showHoverSiderMenu = computed(() => {
  return (
    menuHover.value &&
    !selectedKeys?.value.includes(hoverMenuKey.value) &&
    secondMenus.value &&
    secondMenus.value.length
  );
});

const customItem = (vnode: VNode, opt: any) => {
  return cloneVNode(vnode, {
    class: opt.path === hoverMenuKey.value ? 'hover-menu-active' : '',
  });
};
</script>

<style lang="less">
#app-body {
  @import '../components/base-layouts/leftmenu-layout.less';
  @import '../components/base-layouts/leftmenu/index.less';
}
</style>
